#version 330 core
out vec4 FragColor;
  
in vec2 TexCoords;

uniform sampler2D gPosition;    // 世界空间位置纹理采样器
uniform sampler2D gNormal;      // 法线向量纹理采样器
uniform sampler2D gAlbedoSpec;  // 漫反射颜色 + 高光强度纹理采样器

struct Light {
    vec3 Position;
    vec3 Color;
    
    float Linear;
    float Quadratic;
};

const int NR_LIGHTS = 32;       // 最大光源数量
uniform Light lights[NR_LIGHTS];// 光源数组
uniform vec3 viewPos;           // 观察者位置

void main()
{             
    // 从G缓冲中获取数据
    vec3 FragPos = texture(gPosition, TexCoords).rgb;  // 提取世界坐标
    vec3 Normal = texture(gNormal, TexCoords).rgb;      // 提取法线向量
    vec3 Diffuse = texture(gAlbedoSpec, TexCoords).rgb;  // 提取漫反射颜色
    float Specular = texture(gAlbedoSpec, TexCoords).a; // 提取高光强度
    
    // 按常规方式计算光照
    vec3 lighting = Diffuse * 0.1; // 硬编码的环境光分量
    vec3 viewDir = normalize(viewPos - FragPos);  // 计算观察方向
    for(int i = 0; i < NR_LIGHTS; ++i)
    {
        // diffuse
        vec3 lightDir = normalize(lights[i].Position - FragPos);
        vec3 diffuse = max(dot(Normal, lightDir), 0.0) * Diffuse * lights[i].Color;
        // specular
        vec3 halfwayDir = normalize(lightDir + viewDir);  
        float spec = pow(max(dot(Normal, halfwayDir), 0.0), 16.0);
        vec3 specular = lights[i].Color * spec * Specular;
        // attenuation
        float distance = length(lights[i].Position - FragPos);
        float attenuation = 1.0 / (1.0 + lights[i].Linear * distance + lights[i].Quadratic * distance * distance);
        diffuse *= attenuation;
        specular *= attenuation;
        lighting += diffuse + specular;        
    }
    
    FragColor = vec4(lighting, 1.0);  // 输出最终光照颜色
}  